package com.handong.handserialprogram.thread;

import android.content.Context;

import com.handong.handserialprogram.R;
import com.handong.handserialprogram.model.entities.FootRingEntity;
import com.handong.handserialprogram.model.entities.FootRingEntity;
import com.handong.handserialprogram.model.status.FootRingStatus;
import com.handong.handserialprogram.model.status.RingResponse;
import com.handong.handserialprogram.model.status.SimNetStatus;
import com.handong.handserialprogram.module.serialport.SerialPortUtil;
import com.handong.handserialprogram.utils.CheckUtil;
import com.handong.handserialprogram.utils.EventBusUtil;
import com.handong.handserialprogram.utils.FootRingUtil;
import com.handong.handserialprogram.utils.JLog;
import com.handong.handserialprogram.utils.SPUtil;
import com.handong.handserialprogram.voice.VoiceImpl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

import cn.pda.serialport.Tools;

/**
 * 串口工作线程。
 * Created by userKey on 2017/12/5.
 */

public class ReadRunnable extends BaseRunnable {

    private static final byte DATA_LENGTH = 16;
    private static final byte TIME_WAIT = 9;
    private InputStream mReadStream;
    private Vector<FootRingEntity> mRingList;

    //private byte mIdHigh, mIdLow;
    private VoiceImpl mVoiceImpl;
    private Context mAppContext;
    private SerialPortUtil mSerialPortUtil;

    private boolean mIsPlayWarningVoice = false;//是否开启警报
    private boolean mIsUploadLocation = false;
    private byte mWarningCount, mUploadCount;
    public boolean isFirst=true;
    private byte mTestCount = 0;

    public ReadRunnable(SerialPortUtil serialPortUtil, InputStream readStream, Vector<FootRingEntity> ringList,
                        Context context, boolean isPlayWarningVoice) {
        this.mReadStream = readStream;
        this.mRingList = ringList;
        this.mSerialPortUtil = serialPortUtil;
        this.mAppContext = context;
        this.mIsPlayWarningVoice = isPlayWarningVoice;
    }

    @Override
    public void work() throws RuntimeException {
        if (mRingList == null) {
            return;
        }
       /* if (SerialPortUtil.TEST_DEBUG) {
            //测试情况
            if (mRingList != null && !mRingList.isEmpty()) {
                EventBusUtil.post(mRingList);
                FootRingEntity entity = mRingList.get;
                playWarningRing(entity);

                if (entity.getActionOrder() == RingResponse.LOGOUT_ORDER) {
                    if (mTestCount == 5) {
                        entity.setNormalWork(false);
                        entity.setActionOrder(RingResponse.NO_ACTION_ORDER);
                        //EventBusUtil.post(new RingResponse("88CE", RingResponse.LOGOUT_ORDER, true));
                        mTestCount = 0;
                    }
                    mTestCount++;
                }
            }
        } else {*/
            try {
                //查找更新有效的脚环
                search4ActiveFootRing();
            } catch (IOException e) {
                e.printStackTrace();
            }
       // }
        if (mIsWorking && mIsUploadLocation) {//如果已绑定脚环刷新距离

            if (mUploadCount == 0) {//只上传一次到服务器
                if (!mRingList.isEmpty()) {
                    mSerialPortUtil.refreshRingList();//上传到服务器
//                    if (isFirst){
//                        mSerialPortUtil.startMission(SPUtil.getStringValue(SPUtil.MISSION_ID));
//                        isFirst=false;
//                    }
                }
                mUploadCount++;
            } else {
                mUploadCount++;
                if (mUploadCount == TIME_WAIT) {
                    mUploadCount = 0;
                }
            }
        }
    }

    /**
     * 查找并激活脚环。
     */
    private void search4ActiveFootRing() throws IOException {
        byte[] buff = new byte[mReadStream.available()];//获取全部数据
        //JLog.d(TAG, "Active Data:" + Tools.byteToHexString(buff));
        if ((mReadStream.read(buff)) != 0) {
            if (buff[0] != 0x15) {//0x15 不是脚环发送的 错误数据 || CheckUtil.u8CheckSum8Calibration(buff) != buff[12]
                JLog.d(TAG, "Active Data:" + Tools.byteToHexString(buff));
               // refreshFootRing(false, null);
                refreshAllFootRing(null);//刷新全部脚环
                return;
            }
           //1575005B0001E8C00000000A98 157A00050001E4C40000000A47
            dealActiveBufferByte(buff);//添加或处理脚环命令
        } else {
            //refreshFootRing(false, null);
            refreshAllFootRing(null);//刷新全部脚环
            JLog.d(TAG, Thread.currentThread().getId() + " active work no data.");
        }
    }

    /**
     * 添加或处理脚环命令
     */
    private Vector<FootRingEntity> refFootRings=new Vector<>();
    private void dealActiveBufferByte(byte[] buff) {
        if (mRingList == null) {
            return;
        }



        JLog.d(TAG, "Active Data:" + Tools.byteToHexString(buff));
        FootRingEntity entity = null;
        int index = 0;
        int len = buff.length;
        refFootRings.clear();
        do {

            if (buff[index] != 21) {//0x15 不是脚环发送命令
                index++;//循环到x015为止
                continue;//结束本次循环
            }
            if (index + DATA_LENGTH > len) {//数据是否完整。
                break;
            }
            byte[] tempBuff = new byte[DATA_LENGTH];//13个字节表示一个脚环
            System.arraycopy(buff, index, tempBuff, 0, DATA_LENGTH);

            if(CheckUtil.u8CheckSum8Calibration(tempBuff) != tempBuff[(DATA_LENGTH-1)]){
                JLog.d(TAG, "Active Data:" + Tools.byteToHexString(tempBuff));
                index++;//循环到x015为止
                continue;
            }
            entity= FootRingUtil.getFootRingFromList(tempBuff,mRingList);
            //JLog.d(TAG,"Code:"+Tools.byteToHexString(tempBuff).substring(12,16));
               byte cmd=tempBuff[2];
                 //用户操作命令答复
                if (entity != null && RingResponse.NO_ACTION_ORDER != entity.getActionOrder()) {
                    switch (cmd) {
                        case RingResponse.ACTIVATE_ORDER://脚环自检成功
                            FootRingUtil.unbind(entity);
                            sendDealOrder(entity, RingResponse.ACTIVATE_ORDER, true);
                            entity.setActionOrder(RingResponse.INIT_2GNET_SUCCESS);//自检的时候设置成成功
                            break;
                        case RingResponse.INIT_2GNET_SUCCESS://脚环初始化成功
                            entity.setNormalWork(true);
                            //FootRingUtil.setMyBingding(entity,entity.getIMEI_CCR());
                            FootRingUtil.unbind(entity);
                            sendDealOrder(entity, RingResponse.INIT_2GNET_SUCCESS, true);
                            break;
                        case RingResponse.LOGOUT_ORDER://休眠命令成功
                            FootRingUtil.unbind(entity);
                            entity.setNormalWork(false);
                            mRingList.remove(entity);
                            sendDealOrder(entity, RingResponse.LOGOUT_ORDER, true);
                            break;
                        case RingResponse.UPDATE_DISTANCE_ORDER://设置距离
                            sendDealOrder(entity, RingResponse.UPDATE_DISTANCE_ORDER, true);
                            break;

                        case RingResponse.CLOSE_ALARM_RESPONSE://关闭警报
                            if (RingResponse.CLOSE_ALARM_RESPONSE == entity.getActionOrder()) {
                                sendDealOrder(entity, RingResponse.CLOSE_ALARM_RESPONSE, true);
                                mSerialPortUtil.closeAlarmOrder2Server(entity.getRingID());
                                mUploadCount = 5;
                            } else {
                                entity.setActionOrder(RingResponse.NO_ACTION_ORDER);
                                mSerialPortUtil.resetOrder2Server(entity.getRingID());
                                mUploadCount = 5;
                            }
                            break;
                        case RingResponse.PARAMETER_SET://参数设置模式应答
                            sendDealOrder(entity,RingResponse.PARAMETER_SET, true);
                            break;
                        case RingResponse.PARAMERT_LOGOUT://退出参数设置模式
                            sendDealOrder(entity,RingResponse.PARAMERT_LOGOUT, true);
                            break;
                        case RingResponse.SEVER_IP_SET://服务器参数设置应答
                            sendDealOrder(entity,RingResponse.SEVER_IP_SET, true);
                            break;

                        case RingResponse.ALARM_SOUND_SET://报警声设置应答
                            sendDealOrder(entity,RingResponse.ALARM_SOUND_SET, true);
                            break;


                    }
                }else if(entity==null){
                    //不是脚环命令
                    if(cmd==RingResponse.SEND_ID_SUCCESS){//发送成功
                        sendDealOrder(RingResponse.SEND_ID_SUCCESS, true);
                        continue;
                    }
                }

            refreshFootRingEntity(tempBuff, entity);//添加脚环-设置脚环
            refFootRings.add(entity);
            index += DATA_LENGTH;
        } while (index < len);//未读取完数据继续读取数据。

        refreshAllFootRing(refFootRings);//刷新全部脚环
    }

    /**
     * 发送处理脚环结果
     */
    private void sendDealOrder(FootRingEntity entity, byte order, boolean isSuccess) {
        if (entity == null) {
            return;
        }
        entity.resetActionCount();
        entity.setActionOrder(RingResponse.NO_ACTION_ORDER);//重置为已处理
        EventBusUtil.post(new RingResponse(entity.getRingID(), order, isSuccess));
    }
    private void sendDealOrder(byte order, boolean isSuccess) {
        EventBusUtil.post(new RingResponse(order, isSuccess));
    }


    /**
     * 解析数据实体
     */
    private void refreshFootRingEntity(byte[] buff, FootRingEntity entity) {
        if (mRingList == null) {
            return;
        }
        if(entity==null){
            //没有该脚环添加
            entity = new FootRingEntity();
            mRingList.add(entity);
        }


        byte status = buff[2];//脚环状态
        String imei_crc = Tools.byteLinkByteToHexString(buff, 13, 2);
        entity.setIMEI_CCR(imei_crc);

        int index = 3;//从第三位开始取数据。
        if(status == RingResponse.SEVER_IP){//服务器参数
            FootRingUtil.setSeverParamter(buff, entity, index);
            return;
        }else if(status == RingResponse.SIM_NUMBER){//SIM卡号
            FootRingUtil.setSim(buff, entity, index);
            return;
        }else if(status == RingResponse.VERSION_NUMBER){//版本号
            FootRingUtil.setVersion(buff, entity, index);
            return;
        }


        /**
         * 脚环正常数据
         */
        byte tempDistance = buff[index++];//取第三位
        int distance = Tools.byteLinkByteToInt(tempDistance, buff[index++]);
        if (distance >= 4000) {//超过40米时不用更新
            if (entity != null) {
                entity.setActualRingDistance(39.9f);
            }
            return;
        }
        int setDistance = buff[index++] & 0xFF;//设置距离
        String id = Tools.byteLinkByteToHexString(buff, index, 2);
        byte   mIdHigh = buff[index++];
        byte mIdLow = buff[index++];
        int power = buff[index++];
        int lockType = buff[index++];
        int simStatus = buff[index++];
        int voiceNumber = buff[index++];
        int ses = buff[index++];//预留

        float distanceFloat = CheckUtil.floatRoundToInt(distance);
        entity.setRingID(id);
        entity.setActualRingDistance(distanceFloat);
        entity.setSetRingDistance(setDistance);
        entity.setRingPower(power);
        entity.setVoiceNumber(voiceNumber);

        if (status == RingResponse.ACTIVATE_ORDER) {//自检状态 return
            FootRingUtil.setMyBingding(entity,imei_crc);
            //FootRingUtil.unbind(entity);
            return;
        }else if (status == RingResponse.RING_DEFAULT_STATE) {//默认状态
            FootRingUtil.unbind(entity);
            entity.setNormalWork(false);
            return;
        } else if (status == RingResponse.INIT_2GNET_SUCCESS) {//脚环初始化成功
            FootRingUtil.setMyBingding(entity,imei_crc);
            entity.setNormalWork(true);
            //FootRingUtil.unbind(entity);
            //entity.setRingPower(power);
            return;
        }else if(status==RingResponse.AUTO_LOGOUT||status==RingResponse.LOGOUT_ORDER){// 自动休眠
            FootRingUtil.unbind(entity);
            entity.setNormalWork(false);
            //sendDealOrder(entity, RingResponse.LOGOUT_ORDER, true);
            mRingList.remove(entity);
            return;
        }else if(status == RingResponse.PARAMETER_SET){//参数设置模式
            return;
        }else if(status==RingResponse.ACTIVATED){//激活待绑定时测距
            entity.setNormalWork(true);
            FootRingUtil.setMyBingding(entity,imei_crc);
        } else if (status == RingResponse.RING_ACTIVATE_STATE) {//测距状态（正常模式）
            entity.setNormalWork(true);
            FootRingUtil.setMyBingding(entity,imei_crc);
        }else if(status==RingResponse.PARAMERT_ACTIVATED){//测距状态（参数设置模式)
            entity.setNormalWork(true);
            FootRingUtil.setMyBingding(entity,imei_crc);
            if(!entity.isMyBingding()){//其他手持机去掉
                mRingList.remove(entity);
            }
        }


        /**
         * 激活状态下发声。05之前的状态return
         */

        if (mIsPlayWarningVoice && entity.getLockType() != FootRingEntity.LOCK_OPEN && lockType == FootRingEntity.LOCK_OPEN) {//开锁报警
            if (mVoiceImpl == null) mVoiceImpl = VoiceImpl.getInstance(mAppContext);
            mVoiceImpl.addSound(R.raw.warning_lock_open);
        }
        if (lockType == FootRingEntity.LOCK_OPEN) {
            if(entity.isEmpower())
            {
                entity.setLockType(FootRingEntity.LOCK_EMPOWER_OPEN);
            }
            else{
                entity.setLockType(FootRingEntity.LOCK_OPEN);
            }

        } else {

            entity.setLockType(FootRingEntity.LOCK_CLOSE);
        }
        //entity.setLockType(lockType);


        //报警处理。
        int broken = simStatus >>> 4;//防拆 取高4位
        int sim = simStatus & 3;//取低4位 也可以 &0x0f
        if (FootRingEntity.LOCK_OPEN == broken) {//拆报警
            if (mIsPlayWarningVoice && !entity.getBrokenType()&&!entity.isEmpower()) {
                if (mVoiceImpl == null) mVoiceImpl = VoiceImpl.getInstance(mAppContext);
                mVoiceImpl.addSound(R.raw.warning_ring_broken);
            }
            entity.setBrokenType(true);
        } else {
            entity.setBrokenType(false);
        }
        //0 初始话，1有卡，2无卡 SimNetStatus.SIM_ERROR != entity.getSimStatus()去掉重复发送
        if (sim == SimNetStatus.SIM_ERROR && SimNetStatus.SIM_ERROR != entity.getSimStatus()) {
            entity.setSimStatus(SimNetStatus.SIM_ERROR);
            EventBusUtil.post(new RingResponse(id, RingResponse.SIM_ERROR, false));
        }
    }




    /**
     * 刷新脚环-有命时令执行-处理超时
     * @param isRefresh 是否收到新的数据
     * @param entity 更新的脚环
     */
    private void refreshFootRing(boolean isRefresh, FootRingEntity entity) {
        if (mRingList == null) {//|| (mRingList.isEmpty())
            return;
        }
        if (null == entity) {
            return;
        }
        //处理有命令时未处理完成-超时处理
        if (RingResponse.NO_ACTION_ORDER != entity.getActionOrder()) {
            switch (entity.getActionOrder()) {
                case RingResponse.ACTIVATE_ORDER://脚环激活
                    activateNoResponse(entity, RingResponse.ACTIVATE_ORDER);
                    break;

                case RingResponse.INIT_2GNET_SUCCESS://自检状态-自己设置的
                    dealRingSelfCheck(entity, RingResponse.INIT_2GNET_SUCCESS);
                    break;

                case RingResponse.LOGOUT_ORDER://脚环休眠
                    dealExceptActivateOrder(entity, RingResponse.LOGOUT_ORDER);
                    break;

                case RingResponse.CLOSE_ALARM_RESPONSE://报警关闭
                    dealOverTimeOrder(entity, RingResponse.CLOSE_ALARM_RESPONSE);
                    break;

                case RingResponse.UPDATE_DISTANCE_ORDER://设置距离更新
                    dealOverTimeOrder(entity, RingResponse.UPDATE_DISTANCE_ORDER);
                    break;

                case RingResponse.CLOSE_ALARM_FROM_SERVER://从服务器报警关闭
                    entity.addActionCount();
                    if (entity.getActionCount() == 13) {
                        entity.setAction(false);
                        entity.setActionOrder(RingResponse.NO_ACTION_ORDER);
                    }
                    break;
                case RingResponse.PARAMETER_SET://参数设置模式应答
                    dealOverTimeOrder(entity, RingResponse.PARAMETER_SET);
                    break;
                case RingResponse.PARAMERT_LOGOUT://退出参数设置模式
                    dealOverTimeOrder(entity, RingResponse.PARAMERT_LOGOUT);
                    break;
                case RingResponse.SEVER_IP_SET://服务器参数设置应答
                    dealOverTimeOrder(entity, RingResponse.SEVER_IP_SET);
                    break;
                case RingResponse.ALARM_SOUND_SET://报警声设置应答
                    dealOverTimeOrder(entity, RingResponse.ALARM_SOUND_SET);
                    break;
            }
            JLog.d(TAG, "ActionOrder:" + entity.getActionCount());
        }

        if (isRefresh) {
            entity.resetTime();//重置时间
        } else {
            entity.calculateTime();//计算时间
        }
       playWarningRing(entity);//警报
    }

    /**
     * 更新全部脚环
     * @param refFootRings  有更新的脚环
     */
    private void refreshAllFootRing(Vector<FootRingEntity> refFootRings){
        if (mRingList == null) {//|| (mRingList.isEmpty())
            return;
        }

        for (FootRingEntity entity:mRingList) {
            if(refFootRings!=null&&refFootRings.contains(entity)){
                refreshFootRing(true,entity);//刷新脚环
            }else{
                refreshFootRing(false,entity);//刷新脚环
            }
        }
        EventBusUtil.post(mRingList);//返回列表
    }


    /**
     * 激活应答-超时处理（10秒）
     */
    private void activateNoResponse(FootRingEntity entity, byte order) {
        if (entity.getStatus() == FootRingStatus.ESCAPE) {
            entity.calculateTime();
            sendDealOrder(entity, order, false);
            return;
        }
        entity.addActionCount();
        JLog.d(TAG, "Activate activateNoResponse" + entity.getActionCount());
        if (entity.getActionCount() == 16) {
            mSerialPortUtil.activateFootRing(entity.getRingID());
            return;
        }
        if (entity.getActionCount() == 30) {
            sendDealOrder(entity, order, false);
        }
    }
    /**
     * 自检-超时处理(超过20秒)
     */
    private void dealRingSelfCheck(FootRingEntity entity, byte order) {
        entity.addActionCount();
        JLog.d(TAG, "Activate Receive Response:" + entity.getActionCount());

        if (entity.getActionCount() == FootRingEntity.LONG_WAIT) {
            sendDealOrder(entity, order, false);
        }
    }

    /**
     * 处理休眠超时
     */
    private void dealExceptActivateOrder(FootRingEntity entity, byte order) {
        if (entity.getStatus() == FootRingStatus.ESCAPE) {
            sendDealOrder(entity, order, false);
            return;
        }
        entity.addActionCount();
        if (entity.getActionCount() == 16) {
            if (order == RingResponse.LOGOUT_ORDER) {
                mSerialPortUtil.logoutFootRing(entity.getRingID());
            }
           /* if (order != RingResponse.LOGOUT_ORDER) {
                sendDealOrder(entity, order, false);
                return;
            } else {
                mSerialPortUtil.logoutFootRing(entity.getRingID());
            }*/
        }
        if (entity.getActionCount() == 30) {
            if (order == RingResponse.LOGOUT_ORDER) {
                sendDealOrder(entity, order, false);
            }
        }
    }

    /**
     * 处理部分命令-超时处理
     * 超过10秒超时处理
     */
    private void dealOverTimeOrder(FootRingEntity entity, byte order) {
        if (entity.getStatus() == FootRingStatus.ESCAPE) {
            sendDealOrder(entity, order, false);
            return;
        }
        entity.addActionCount();
        if (entity.getActionCount() == 30) {
            sendDealOrder(entity, order, false);
        }
    }

    /**
     * 播放警报
     */
    private void playWarningRing(FootRingEntity entity) {
        if (!entity.isNormalWork()) {
            return;
        }
        if (!mIsPlayWarningVoice) {
            mWarningCount = 0;
            return;
        }
        if (mVoiceImpl == null) {
            mVoiceImpl = VoiceImpl.getInstance(mAppContext);
        }
        // TODO: 2017/11/23 可以考虑重置标识符，来缩短首次报警的时间差。
        if (mWarningCount != 0) {
            mWarningCount++;
            if (mWarningCount == TIME_WAIT) {
                mWarningCount = 0;
            }
            return;
        }
        mWarningCount++;
        if (FootRingStatus.ESCAPE != entity.getStatus() && entity.getRingPower() <= 65) {
            mVoiceImpl.addSound(R.raw.warning_ring_low_power);//低电量
        }
        if (FootRingStatus.ESCAPE != entity.getStatus() && entity.getSetRingDistance() < entity.getActualRingDistance()) {
            mVoiceImpl.addSound(R.raw.warning_exception);//异常音效
        }
        if (entity.getStatus() == FootRingStatus.ESCAPE) {
            mVoiceImpl.addSound(R.raw.warning_escape);//逃脱音效
        }
        mVoiceImpl.playVoice();
    }

    public void setPlayWarningVoice(boolean playWarningVoice) {
        mIsPlayWarningVoice = playWarningVoice;
    }

    public void setUploadLocation(boolean uploadLocation) {
        mIsUploadLocation = uploadLocation;
    }





    @Override
    public void releaseRes() {
        mRingList = null;
        mSerialPortUtil = null;
        mReadStream = null;
        mAppContext = null;
        if (mVoiceImpl != null) {
            mVoiceImpl.releaseRes();
            mVoiceImpl = null;
        }
        mWarningCount = 0;
        mUploadCount = 0;
        //mIdHigh = 0;
       // mIdLow = 0;
    }
}
